<?php

namespace app\admin\controller\auth;

use app\admin\model\AuthGroup;
use app\admin\model\AuthGroupAccess;
use app\common\controller\Backend;
use fast\Random;
use fast\Tree;
use think\Db;
use think\Exception;
use think\Validate;
use app\admin\model\department\Department as DepartmentModel;

/**
 * 管理员管理
 *
 * @icon   fa fa-users
 * @remark 一个管理员可以有多个角色组,左侧的菜单根据管理员所拥有的权限进行生成
 */
class Admin extends Backend
{

    /**
     * @var \app\admin\model\Admin
     */
    protected $relationSearch = true;
    protected $model = null;
    protected $selectpageFields = 'id,username,nickname,avatar';
    protected $searchFields = 'id,username,nickname';
    protected $childrenGroupIds = [];
    protected $childrenAdminIds = [];

    public function _initialize()
    {
        parent::_initialize();
        $this->model = model('Admin');

        $this->childrenAdminIds = $this->auth->getChildrenAdminIds($this->auth->isSuperAdmin());
        $this->childrenGroupIds = $this->auth->getChildrenGroupIds($this->auth->isSuperAdmin());

        $groupList = collection(AuthGroup::where('id', 'in', $this->childrenGroupIds)->select())->toArray();
        foreach ($groupList as &$value) {
            $value['pid'] = 0;
        }
        Tree::instance()->init($groupList);
        $groupdata = [];
        if ($this->auth->isSuperAdmin()) {
            $result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
            foreach ($result as $k => $v) {
                $groupdata[$v['id']] = $v['name'];
            }
        } else {
            $result = [];
            $groups = $this->auth->getGroups();
            foreach ($groups as $m => $n) {
                $childlist = Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['id']));
                $temp = [];
                foreach ($childlist as $k => $v) {
                    $temp[$v['id']] = $v['name'];
                }
                $result[__($n['name'])] = $temp;
            }
            $groupdata = $result;
        }

        $this->view->assign('groupdata', $groupdata);
        $this->assignconfig("admin", ['id' => $this->auth->id]);
    }

    /**
     * 查看
     */
    public function index()
    {
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            $childrenGroupIds = $this->childrenGroupIds;
            $groupName = AuthGroup::where('id', 'in', $childrenGroupIds)
                ->column('id,name');
            $authGroupList = AuthGroupAccess::where('group_id', 'in', $childrenGroupIds)
                ->field('uid,group_id')
                ->select();

            $adminGroupName = [];
            foreach ($authGroupList as $k => $v) {
                if (isset($groupName[$v['group_id']])) {
                    $adminGroupName[$v['uid']][$v['group_id']] = $groupName[$v['group_id']];
                }
            }
            $groups = $this->auth->getGroups();
            foreach ($groups as $m => $n) {
                $adminGroupName[$this->auth->id][$n['id']] = $n['name'];
            }

            $this->tree = Tree::instance();
            $this->tree->init(\app\admin\model\department\Department::allDepartment(), 'parent_id');
            $departmentQuery = [];
            $filter = $this->request->request('filter');
            $filterArr = (array)json_decode($filter, true);
            if (isset($filterArr['department_id'])) {
                $departmentId = $filterArr['department_id'];
                $filterArr = array_diff_key($filterArr, ['department_id' => '']);
                $departmentQuery = function ($query) use ($departmentId) {
                    $departmentIds = $this->tree->getChildrenIds($departmentId, true);
                    $query->whereIn('department_id', $departmentIds);
                };
            }
            $this->request->get(['filter' => json_encode($filterArr)]);

            list($where, $sort, $order, $offset, $limit) = $this->buildparams();

            $list = $this->model
                ->with(["department", "position", "type"])
                ->where($departmentQuery)
                ->where($where)
                ->where('admin.id', 'in', $this->childrenAdminIds)
//                ->field(['password', 'salt', 'token'], true)
                ->order($sort, $order)
                ->paginate($limit);

            foreach ($list as $k => &$v) {
                $departmentList = $this->tree->getParents($v['department_id'], false);
                $str = '';
                foreach ($departmentList as $k => &$value) {
                    $temp['name']=str_replace("&nbsp;", " ", strip_tags($value['name'])); //过滤空格
                    $str .= $temp['name'] . ",";
                }
                $v['department_name'] = $str .= ($v['department']['name'] ?? '');

                $groups = isset($adminGroupName[$v['id']]) ? $adminGroupName[$v['id']] : [];
                $v['groups'] = implode(',', array_keys($groups));
                $v['groups_text'] = implode(',', array_values($groups));
                $v->hidden(['password', 'salt', 'token']);
            }
            unset($v);
            $result = array("total" => $list->total(), "rows" => $list->items());

            return json($result);
        }
        return $this->view->fetch();
    }

    /**
     * 添加
     */
    public function add()
    {
        if ($this->request->isPost()) {
            $this->token();
            $params = $this->request->post("row/a");
            if ($params) {
                Db::startTrans();
                try {
                    if (!Validate::is($params['password'], '\S{6,30}')) {
                        exception(__("Please input correct password"));
                    }
                    $params['salt'] = Random::alnum();
                    $params['password'] = md5(md5($params['password']) . $params['salt']);
                    $params['avatar'] = '/assets/img/avatar.png'; //设置新管理员默认头像。
//                    $params['nickname'] = $params['username'];
                    $result = $this->model->validate('Admin.add')->save($params);
                    if ($result === false) {
                        exception($this->model->getError());
                    }
                    $group = $this->request->post("group/a");

                    //过滤不允许的组别,避免越权
                    $group = array_intersect($this->childrenGroupIds, $group);
                    if (!$group) {
                        exception(__('The parent group exceeds permission limit'));
                    }

                    $dataset = [];
                    foreach ($group as $value) {
                        $dataset[] = ['uid' => $this->model->id, 'group_id' => $value];
                    }
                    model('AuthGroupAccess')->saveAll($dataset);
                    Db::commit();
                } catch (\Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                $this->success();
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        return $this->view->fetch();
    }

    /**
     * 编辑
     */
    public function edit($ids = null)
    {
        $row = $this->model->get(['id' => $ids]);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        if (!in_array($row->id, $this->childrenAdminIds)) {
            $this->error(__('You have no permission'));
        }
        if ($this->request->isPost()) {
            $this->token();
            $params = $this->request->post("row/a");
            if ($params) {
                Db::startTrans();
                try {
                    if ($params['password']) {
                        if (!Validate::is($params['password'], '\S{6,30}')) {
                            exception(__("Please input correct password"));
                        }
                        $params['salt'] = Random::alnum();
                        $params['password'] = md5(md5($params['password']) . $params['salt']);
                    } else {
                        unset($params['password'], $params['salt']);
                    }
                    //这里需要针对username和email做唯一验证
                    $adminValidate = \think\Loader::validate('Admin');
                    $adminValidate->rule([
                        'username' => 'require|regex:\w{3,30}|unique:admin,username,' . $row->id,
//                        'email'    => 'require|email|unique:admin,email,' . $row->id,
//                        'mobile'    => 'regex:1[3-9]\d{9}|unique:admin,mobile,' . $row->id,
                        'password' => 'regex:\S{32}',
                    ]);
//                    $params['nickname'] = $params['username'];
                    $result = $row->validate('Admin.edit')->save($params);
                    if ($result === false) {
                        exception($row->getError());
                    }

                    // 先移除所有权限
                    model('AuthGroupAccess')->where('uid', $row->id)->delete();

                    $group = $this->request->post("group/a");

                    // 过滤不允许的组别,避免越权
                    $group = array_intersect($this->childrenGroupIds, $group);
                    if (!$group) {
                        exception(__('The parent group exceeds permission limit'));
                    }

                    $dataset = [];
                    foreach ($group as $value) {
                        $dataset[] = ['uid' => $row->id, 'group_id' => $value];
                    }
                    model('AuthGroupAccess')->saveAll($dataset);
                    Db::commit();
                } catch (\Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                $this->success();
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $grouplist = $this->auth->getGroups($row['id']);
        $groupids = [];
        foreach ($grouplist as $k => $v) {
            $groupids[] = $v['id'];
        }
        $this->view->assign("row", $row);
        $this->view->assign("groupids", $groupids);
        return $this->view->fetch();
    }

    /**
     * 删除
     */
    public function del($ids = "")
    {
        if (!$this->request->isPost()) {
            $this->error(__("Invalid parameters"));
        }
        $ids = $ids ? $ids : $this->request->post("ids");
        if ($ids) {
            $ids = array_intersect($this->childrenAdminIds, array_filter(explode(',', $ids)));
            // 避免越权删除管理员
            $childrenGroupIds = $this->childrenGroupIds;
            $adminList = $this->model->where('id', 'in', $ids)->where('id', 'in', function ($query) use ($childrenGroupIds) {
                $query->name('auth_group_access')->where('group_id', 'in', $childrenGroupIds)->field('uid');
            })->select();
            if ($adminList) {
                $deleteIds = [];
                $deleteUsername = [];
                foreach ($adminList as $k => $v) {
                    $deleteIds[] = $v->id;
                    $deleteUsername[] = $v->username;
                }
                $deleteIds = array_values(array_diff($deleteIds, [$this->auth->id]));
                if ($deleteIds) {
                    //删除用户所关联的项目和项目作者关系
                    $this->_handleArticleAuthor($deleteIds, $deleteUsername);
                    Db::startTrans();
                    try {
                        $this->model->destroy($deleteIds);
                        model('AuthGroupAccess')->where('uid', 'in', $deleteIds)->delete();
                        Db::commit();
                    } catch (\Exception $e) {
                        Db::rollback();
                        $this->error($e->getMessage());
                    }
                    $this->success();
                }
                $this->error(__('No rows were deleted'));
            }
        }
        $this->error(__('You have no permission'));
    }

    private function _handleArticleAuthor($deleteIds, $deleteUsername)
    {
        $articleModel = new \app\admin\model\department\Article;
        foreach ($deleteUsername as $v) {
            $articleWhere = [
                "author|first_author" => ['like' , "%{$v}%"]
            ];
            $tempNames = $articleModel->where($articleWhere)->select();
            foreach ($tempNames as $val) {
                $tempName = explode(",", $val['author']);
                $nameIndex = array_search($v, $tempName);
                if ($nameIndex) {
                    unset($tempName[$nameIndex]);
                    $authorTemp = implode(",", $tempName);
                    $val->author = $authorTemp ?? '';
                    $val->save();
                }
                if ($val['first_author'] == $v) {
                    $val->first_author = '';
                    $val->save();
                }
            }
        }
        \app\admin\model\department\ArticleUser::where('user_id', 'in', $deleteIds)->delete();
    }

    /**
     * 批量更新
     * @internal
     */
    public function multi($ids = "")
    {
        // 管理员禁止批量操作
        $this->error();
    }

    public function resetpwd($ids = null)
    {
        $pwd = "123456";
        $params['salt'] = Random::alnum();
        $params['password'] = md5(md5($pwd) . $params['salt']);
        $this->model->whereIn("id", $ids)->update($params);
        $this->success("重置成功");
    }


    public function excel()
    {
        if ($this->request->isPost()) {
            ini_set('memory_limit', '-1'); //设置为不限制
            set_time_limit(0);  //设置为不限制

            $fileName = input('pdf');
            $fileName = str_replace($_SERVER["REQUEST_SCHEME"] . "://" . $_SERVER["SERVER_NAME"], '', $fileName);
            $file = $_SERVER ["DOCUMENT_ROOT"] . $fileName;
            $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx');
            $reader->setReadDataOnly(true);  //过滤excel中的特殊字符
            $PHPExcel = $reader->load($file);
            $sheet = $PHPExcel->getSheet(0); // 读取第一個工作表
            $highestRow = $sheet->getHighestRow(); // 取得总行数
            $highestColumn = $sheet->getHighestColumn(); // 取得总列数
            $data = [];

            for ($row = 2; $row <= $highestRow; $row++) { //行号从1开始
                for ($column = 'A'; $column <= $highestColumn; $column++) { //列数是以A列开始
                    if (empty($sheet->getCell($column . $row)->getValue()) == false) {
                        $data[$row][$column] = $sheet->getCell($column . $row)->getValue();
                    }
                }
//                if (!isset($data[$row]['B'])) unset($data[$row]);
            }
//            halt($data);
            Db::startTrans();
            try {
                $dataArr = [];
                $j = 2;
                foreach ($data as $k => $v) {
                    if (empty($v['A'])) {
                        $this->error("第【{$j}】行的姓名未填，请修改后重试");
                    }
                    if (empty($v['B'])) {
                        $this->error("第【{$j}】行的登录名未填，请修改后重试");
                    }
                    if (empty($v['C'])) {
                        $this->error("第【{$j}】行的密码未填，请修改后重试");
                    }
                    if (empty($v['E'])) {
                        $this->error("第【{$j}】行的部门未填，请修改后重试");
                    }
                    $exits = $this->model->where('nickname', $v['A'])->value('id');
                    if (!empty($exits)) {
                        $this->error("第【{$j}】行的姓名已存在，请修改后重试");
                    }
                    $exits = $this->model->where('username', $v['B'])->value('id');
                    if (!empty($exits)) {
                        $this->error("第【{$j}】行的用户名已存在，请修改后重试");
                    }
                    $j++;
                }
                foreach ($data as $k => $v) {
                    $res = [
                        "nickname" => $v['A'],
                        "username" => $v['B'],
                        "email" => '',
                        "mobile" => '',
                        "salt" => Random::alnum(),
                        "avatar" => "/assets/img/avatar.png",
                        "department_id" => $this->_getDepartmentId($v['E']),
                        "position_id" => $this->_getPositionId($v['F']),
//                        "grouping_id" => $this->_getGroupingId($v['H']),
                        "type_id" => $this->_getTypeId($v['G']),
                    ];
                    $res['password'] = md5(md5($v['C']) . $res['salt']);
                    $id = $this->model->insertGetId($res);

                    if (!empty($v['C'])) {
                        //权限组
                        $groupId = model('AuthGroup')->where(['name' => $v['D']])->value('id');
                        $groupData = [
                            "uid" => $id,
                            "group_id" => $groupId,
                        ];
                        model('AuthGroupAccess')->insert($groupData);
                    }
                }

                Db::commit();
                $this->success();
            } catch (Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }

        }
        $doc = "/template/excel/用户导入模板.xlsx";
        $this->view->assign("doc", $doc);
        return $this->view->fetch();
    }

    //获取部门id
    private function _getDepartmentId($name)
    {
        $departmentArr = explode("-", $name);
        $model = new \app\admin\model\department\Department;
        $where = [];
        $id = null;
        foreach ($departmentArr as $value) {
            $where['name'] = $value;
            $id = $model->where($where)->value("id");
            if (empty($id)) {
                break;
            }
            $where['parent_id'] = $id;
        }
        return $id;
    }
    //获取职位ID
    private function _getPositionId($name)
    {
        if (empty($name)) return null;
        $model = new \app\admin\model\department\Position;
        $id = $model->where("name", $name)->value("id");
        return $id;
    }
    //获取类别ID
    private function _getTypeId($name)
    {
        if (empty($name)) return null;
        $model = new \app\admin\model\department\Type;
        $id = $model->where("name", $name)->value("id");
        return $id;
    }
    //获取小组ID
    private function _getGroupingId($name)
    {
        if (empty($name)) return null;
        $model = new \app\admin\model\department\Grouping;
        $id = $model->where("name", $name)->value("id");
        return $id;
    }

    /**
     * 下拉搜索
     */
    public function selectpage()
    {
        $this->dataLimit = 'auth';
        $this->dataLimitField = 'id';
        return parent::selectpage();
    }
}
